/**
 * 自定义节点类型模型
 * 用于存储自定义节点类型的基本信息、代码和版本管理
 */
const fs = require('fs')
const path = require('path')
const { v4: uuidv4 } = require('uuid')

// 数据存储路径
const DATA_DIR = path.join(__dirname, '../data')
const CUSTOM_NODE_TYPES_FILE = path.join(DATA_DIR, 'customNodeTypes.json')
const CUSTOM_NODE_VERSIONS_FILE = path.join(DATA_DIR, 'customNodeVersions.json')
const PUBLISHED_VERSIONS_FILE = path.join(DATA_DIR, 'publishedVersions.json')
const EVENTS_DIR = path.join(__dirname, '../../database/events')
const CATEGORIES_FILE = path.join(__dirname, '../../database/categories.json')

// 确保数据目录存在
if (!fs.existsSync(DATA_DIR)) {
  fs.mkdirSync(DATA_DIR, { recursive: true })
}

// 初始化数据文件
if (!fs.existsSync(CUSTOM_NODE_TYPES_FILE)) {
  fs.writeFileSync(CUSTOM_NODE_TYPES_FILE, JSON.stringify([]))
}

if (!fs.existsSync(CUSTOM_NODE_VERSIONS_FILE)) {
  fs.writeFileSync(CUSTOM_NODE_VERSIONS_FILE, JSON.stringify([]))
}

if (!fs.existsSync(PUBLISHED_VERSIONS_FILE)) {
  fs.writeFileSync(PUBLISHED_VERSIONS_FILE, JSON.stringify([]))
}

/**
 * 读取自定义节点类型列表
 * @returns {Array} 自定义节点类型数组
 */
function getCustomNodeTypes() {
  const data = fs.readFileSync(CUSTOM_NODE_TYPES_FILE, 'utf8')
  return JSON.parse(data)
}

/**
 * 保存自定义节点类型列表
 * @param {Array} customNodeTypes - 自定义节点类型数组
 */
function saveCustomNodeTypes(customNodeTypes) {
  fs.writeFileSync(CUSTOM_NODE_TYPES_FILE, JSON.stringify(customNodeTypes, null, 2))
}

/**
 * 根据ID获取自定义节点类型
 * @param {string} id - 自定义节点类型ID
 * @returns {Object|null} 自定义节点类型对象或null
 */
function getCustomNodeTypeById(id) {
  const customNodeTypes = getCustomNodeTypes()
  return customNodeTypes.find(nodeType => nodeType.id === id) || null
}

/**
 * 创建新的自定义节点类型
 * @param {Object} nodeType - 自定义节点类型数据
 * @returns {Object} 创建的自定义节点类型对象
 */
function createCustomNodeType(nodeType) {
  const customNodeTypes = getCustomNodeTypes()
  
  const newNodeType = {
    id: uuidv4(),
    name: nodeType.name,
    description: nodeType.description || '',
    parametersDocs: nodeType.parametersDocs || '',
    returnDocs: nodeType.returnDocs || '',
    code: nodeType.code || '',
    createTime: nodeType.createTime || new Date().toLocaleDateString(),
    published: false,
    currentVersion: null,
    currentVersionId: null
  }
  
  customNodeTypes.push(newNodeType)
  saveCustomNodeTypes(customNodeTypes)
  
  return newNodeType
}

/**
 * 更新自定义节点类型
 * @param {string} id - 自定义节点类型ID
 * @param {Object} nodeType - 更新的自定义节点类型数据
 * @returns {Object|null} 更新后的自定义节点类型对象或null
 */
function updateCustomNodeType(id, nodeType) {
  const customNodeTypes = getCustomNodeTypes()
  const index = customNodeTypes.findIndex(item => item.id === id)
  
  if (index === -1) {
    return null
  }
  
  // 保留ID和发布状态等信息
  const updatedNodeType = {
    ...customNodeTypes[index],
    name: nodeType.name,
    description: nodeType.description || customNodeTypes[index].description,
    parametersDocs: nodeType.parametersDocs || customNodeTypes[index].parametersDocs,
    returnDocs: nodeType.returnDocs || customNodeTypes[index].returnDocs,
    code: nodeType.code || customNodeTypes[index].code
  }
  
  customNodeTypes[index] = updatedNodeType
  saveCustomNodeTypes(customNodeTypes)
  
  return updatedNodeType
}

/**
 * 删除自定义节点类型
 * @param {string} id - 自定义节点类型ID
 * @returns {boolean} 是否删除成功
 */
function deleteCustomNodeType(id) {
  const customNodeTypes = getCustomNodeTypes()
  const filtered = customNodeTypes.filter(item => item.id !== id)
  
  if (filtered.length === customNodeTypes.length) {
    return false // 没有找到要删除的项
  }
  
  saveCustomNodeTypes(filtered)
  
  // 同时删除相关的版本
  const versions = getCustomNodeVersions()
  const filteredVersions = versions.filter(version => version.nodeTypeId !== id)
  saveCustomNodeVersions(filteredVersions)
  
  // 同时删除发布的版本
  const published = getPublishedVersions()
  const filteredPublished = published.filter(version => version.nodeTypeId !== id)
  savePublishedVersions(filteredPublished)
  
  return true
}

/**
 * 读取自定义节点类型版本列表
 * @returns {Array} 版本数组
 */
function getCustomNodeVersions() {
  const data = fs.readFileSync(CUSTOM_NODE_VERSIONS_FILE, 'utf8')
  return JSON.parse(data)
}

/**
 * 保存自定义节点类型版本列表
 * @param {Array} versions - 版本数组
 */
function saveCustomNodeVersions(versions) {
  fs.writeFileSync(CUSTOM_NODE_VERSIONS_FILE, JSON.stringify(versions, null, 2))
}

/**
 * 获取指定节点类型的所有版本
 * @param {string} nodeTypeId - 自定义节点类型ID
 * @returns {Array} 版本数组
 */
function getVersionsByNodeTypeId(nodeTypeId) {
  const versions = getCustomNodeVersions()
  return versions.filter(version => version.nodeTypeId === nodeTypeId)
}

/**
 * 根据ID获取版本
 * @param {string} versionId - 版本ID
 * @returns {Object|null} 版本对象或null
 */
function getVersionById(versionId) {
  const versions = getCustomNodeVersions()
  return versions.find(version => version.id === versionId) || null
}

/**
 * 创建新版本
 * @param {string} nodeTypeId - 自定义节点类型ID
 * @param {Object} version - 版本数据
 * @returns {Object|null} 创建的版本对象或null
 */
function createVersion(nodeTypeId, version) {
  const nodeType = getCustomNodeTypeById(nodeTypeId)
  if (!nodeType) {
    return null
  }
  
  const versions = getCustomNodeVersions()
  
  // 创建新版本
  const newVersion = {
    id: version.id || uuidv4(),
    nodeTypeId,
    version: version.version,
    description: version.description || '',
    code: version.code || nodeType.code,
    parametersDocs: version.parametersDocs || nodeType.parametersDocs,
    returnDocs: version.returnDocs || nodeType.returnDocs,
    createTime: version.createTime || new Date().toLocaleDateString()
  }
  
  versions.push(newVersion)
  saveCustomNodeVersions(versions)
  
  return newVersion
}

/**
 * 发布版本
 * @param {string} nodeTypeId - 自定义节点类型ID
 * @param {string} versionId - 版本ID
 * @returns {Object|null} 发布的版本对象或null
 */
function publishVersion(nodeTypeId, versionId) {
  const nodeType = getCustomNodeTypeById(nodeTypeId)
  if (!nodeType) {
    return null
  }
  
  const version = getVersionById(versionId)
  if (!version || version.nodeTypeId !== nodeTypeId) {
    return null
  }
  
  // 更新节点类型的发布状态
  const customNodeTypes = getCustomNodeTypes()
  const nodeTypeIndex = customNodeTypes.findIndex(item => item.id === nodeTypeId)
  
  if (nodeTypeIndex === -1) {
    return null
  }
  
  customNodeTypes[nodeTypeIndex].published = true
  customNodeTypes[nodeTypeIndex].currentVersion = version.version
  customNodeTypes[nodeTypeIndex].currentVersionId = versionId
  
  saveCustomNodeTypes(customNodeTypes)
  
  // 保存到已发布版本列表
  const published = getPublishedVersions()
  
  // 先移除该节点类型的旧发布版本
  const filteredPublished = published.filter(item => item.nodeTypeId !== nodeTypeId)
  
  // 添加新的发布版本
  const publishedVersion = {
    id: versionId,
    nodeTypeId,
    name: nodeType.name,
    description: nodeType.description,
    version: version.version,
    code: version.code,
    parametersDocs: version.parametersDocs,
    returnDocs: version.returnDocs,
    publishTime: new Date().toLocaleDateString()
  }
  
  filteredPublished.push(publishedVersion)
  savePublishedVersions(filteredPublished)
  
  return publishedVersion
}

/**
 * 读取已发布的版本列表
 * @returns {Array} 已发布版本数组
 */
function getPublishedVersions() {
  const data = fs.readFileSync(PUBLISHED_VERSIONS_FILE, 'utf8')
  return JSON.parse(data)
}

/**
 * 保存已发布的版本列表
 * @param {Array} versions - 版本数组
 */
function savePublishedVersions(versions) {
  fs.writeFileSync(PUBLISHED_VERSIONS_FILE, JSON.stringify(versions, null, 2))
}

/**
 * 查找使用特定自定义节点类型的所有事件
 * @param {string} nodeTypeId - 自定义节点类型ID
 * @param {number} page - 页码
 * @param {number} pageSize - 每页数量
 * @returns {Object} 事件列表和分页信息
 */
function findEventsUsingCustomNodeType(nodeTypeId, page = 1, pageSize = 10) {
  // 获取自定义节点类型
  const nodeType = getCustomNodeTypeById(nodeTypeId)
  if (!nodeType) {
    return { events: [], total: 0 }
  }
  
  // 获取该节点类型的所有已发布版本ID
  const versions = getVersionsByNodeTypeId(nodeTypeId)
  const versionIds = versions.map(v => v.id)
  
  // 获取所有事件
  const allEvents = []
  
  // 确保事件目录存在
  if (!fs.existsSync(EVENTS_DIR)) {
    return { events: [], total: 0 }
  }
  
  const eventFiles = fs.readdirSync(EVENTS_DIR)
  
  // 检查事件中是否使用了该自定义节点类型
  for (const file of eventFiles) {
    if (file.endsWith('.json')) {
      try {
        const eventContent = fs.readFileSync(path.join(EVENTS_DIR, file), 'utf8')
        const event = JSON.parse(eventContent)
        
        // 新方法：首先检查versionReferences
        let hasCustomNodeType = false
        
        if (event.versionReferences && Array.isArray(event.versionReferences)) {
          hasCustomNodeType = event.versionReferences.some(ref => 
            ref.nodeTypeId === nodeTypeId
          )
        }
        
        // 兼容旧方法：如果没有找到versionReferences，则检查节点
        if (!hasCustomNodeType && event.nodes && Array.isArray(event.nodes)) {
          hasCustomNodeType = event.nodes.some(node => 
            node.type === 'custom' && 
            node.customNodeTypeId === nodeTypeId
          )
        }
        
        if (hasCustomNodeType) {
          // 获取事件分类信息
          const category = getCategoryById(event.categoryId)
          
          allEvents.push({
            id: event.id,
            name: event.name,
            category: category ? category.name : '未分类',
            createTime: event.createTime || '未知'
          })
        }
      } catch (error) {
        console.error(`读取事件文件 ${file} 失败:`, error)
      }
    }
  }
  
  // 计算分页
  const startIndex = (page - 1) * pageSize
  const paginatedEvents = allEvents.slice(startIndex, startIndex + pageSize)
  
  return {
    events: paginatedEvents,
    total: allEvents.length
  }
}

/**
 * 根据版本ID查找使用特定版本的所有事件
 * @param {string} versionId - 版本ID
 * @param {number} page - 页码
 * @param {number} pageSize - 每页数量
 * @returns {Object} 事件列表和分页信息
 */
function findEventsByVersionId(versionId, page = 1, pageSize = 10) {
  const version = getVersionById(versionId)
  if (!version) {
    return { events: [], total: 0 }
  }
  
  // 获取所有事件
  const allEvents = []
  
  // 确保事件目录存在
  if (!fs.existsSync(EVENTS_DIR)) {
    return { events: [], total: 0 }
  }
  
  const eventFiles = fs.readdirSync(EVENTS_DIR)
  
  // 检查事件中是否使用了该版本
  for (const file of eventFiles) {
    if (file.endsWith('.json')) {
      try {
        const eventContent = fs.readFileSync(path.join(EVENTS_DIR, file), 'utf8')
        const event = JSON.parse(eventContent)
        
        // 检查versionReferences
        let hasVersion = false
        
        if (event.versionReferences && Array.isArray(event.versionReferences)) {
          hasVersion = event.versionReferences.some(ref => 
            ref.versionId === versionId
          )
        }
        
        // 兼容旧方法：如果没有找到versionReferences，则检查节点
        if (!hasVersion && event.nodes && Array.isArray(event.nodes)) {
          hasVersion = event.nodes.some(node => 
            node.type === 'custom' && 
            node.customNodeVersionId === versionId
          )
        }
        
        if (hasVersion) {
          // 获取事件分类信息
          const category = getCategoryById(event.categoryId)
          
          allEvents.push({
            id: event.id,
            name: event.name,
            category: category ? category.name : '未分类',
            createTime: event.createTime || '未知'
          })
        }
      } catch (error) {
        console.error(`读取事件文件 ${file} 失败:`, error)
      }
    }
  }
  
  // 计算分页
  const startIndex = (page - 1) * pageSize
  const paginatedEvents = allEvents.slice(startIndex, startIndex + pageSize)
  
  return {
    events: paginatedEvents,
    total: allEvents.length
  }
}

/**
 * 获取分类信息
 * @param {string} categoryId - 分类ID
 * @returns {Object|null} 分类对象或null
 */
function getCategoryById(categoryId) {
  try {
    if (!fs.existsSync(CATEGORIES_FILE)) {
      return null
    }
    
    const categoriesContent = fs.readFileSync(CATEGORIES_FILE, 'utf8')
    const categories = JSON.parse(categoriesContent)
    
    return categories.find(c => c.id === categoryId) || null
  } catch (error) {
    console.error('获取分类信息失败:', error)
    return null
  }
}

module.exports = {
  getCustomNodeTypes,
  getCustomNodeTypeById,
  createCustomNodeType,
  updateCustomNodeType,
  deleteCustomNodeType,
  getVersionsByNodeTypeId,
  getVersionById,
  createVersion,
  publishVersion,
  getPublishedVersions,
  findEventsUsingCustomNodeType,
  findEventsByVersionId
} 